package org.sxdata.jingwei.util.CommonUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

/**
 * @author lidongyang
 * @description:给Http使用的保证线程安全 由于在同一时间多个连接只能安全地用于单一线程和方法和有限的资源，我们就必须确保连接分配给正确的方法
 * HttpClient就在多线程中执行多个方法了。当我们再次调用httpClient.executeMethod()方法时， 就会去Connection
 * Manager中去请求HttpConneciton的实例，这样就避免了线程安全问题 <／p>
 * @date 2018/06/05
 */
public class HttpUtil {
	
	
	private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);
	
	
	public static String httpPostRequest(String url, Map<String, Object> header, String data) {
		return sendPostUrl(url, header, data);
	}
	
	public static String httpPostRequest(String url, Map<String, Object> header, Map<String, String> params) throws RuntimeException {
		String param = "";
		int i = 0;
		int c = params.size();
		if (params != null) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				
				if (i != c - 1) {
					param += entry.getKey() + "=" + entry.getValue() + "&";
				} else {
					param += entry.getKey() + "=" + entry.getValue();
				}
				i++;
			}
		}
		return httpRequestWrapper("POST", url, header, param);
	}
	
	public static String httpGetRequest(String url) {
		return httpRequestWrapper("GET", url, null, null);
		
	}
	
	public static String httpGetRequest(String url, Map<String, Object> header) {
		
		return httpRequestWrapper("GET", url, header, null);
		
	}
	
	
	public static String httpGetRequest(String url, Map<String, Object> header, String data) {
		return httpRequestWrapper("GET", url, header, data);
	}
	
	public static String httpPutRequest(String url, Map<String, Object> header, String params) {
		return httpRequestWrapper("PUT", url, header, params);
	}
	
	public static String httpRequestWrapper(String method, String ourl, Map<String, Object> header, String params) throws RuntimeException {
		long startTime, endTime, costTime;
		startTime = System.currentTimeMillis();
		try {
			return httpRequest(method, ourl, header, params);
		} finally {
			endTime = System.currentTimeMillis();
			costTime = endTime - startTime;
			logger.info("call url:{},cost:{}ms", ourl, costTime);
		}
	}

	private static String httpRequest(String method, String ourl, Map<String, Object> header, String params) throws RuntimeException {
		System.out.println("post参数："+params);
		OutputStream outputstream = null;
		BufferedReader in = null;
		HttpURLConnection httpURLConnection = null;
		try {
			URL url = new URL(ourl);
			httpURLConnection = (HttpURLConnection) url.openConnection();
			httpURLConnection.setConnectTimeout(10 * 1000);
			httpURLConnection.setReadTimeout(10 * 1000);
			httpURLConnection.setDoOutput(true);
			httpURLConnection.setRequestMethod(method);
			httpURLConnection.setUseCaches(false);
			if (header != null && !header.isEmpty()) {
				for (Map.Entry<String, Object> entry : header.entrySet()) {
					httpURLConnection.setRequestProperty(entry.getKey(), (String) entry.getValue());
				}
			}
			if (null != params) {
				OutputStreamWriter out = new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8");
				out.write(params);
				out.flush();
			}
			StringBuffer result = new StringBuffer();
			in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
			String line;
			while ((line = in.readLine()) != null) {
				result.append(line);
			}
			return result.toString();
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		} finally {
			if (outputstream != null) {
				try {
					outputstream.close();
				} catch (IOException e) {
					logger.error(e.getMessage(), e);
					outputstream = null;
				}
			}
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					logger.error(e.getMessage(), e);
					in = null;
				}
			}
		}
	}
	
	/**
	 * POST请求，字符串形式数据
	 *
	 * @param url    请求地址
	 * @param header 请求头
	 * @param param  请求数据
	 */
	private static String sendPostUrl(String url, Map<String, Object> header, String param) {
		return httpRequestWrapper("POST", url, header, param);
	}
	
	/**
	 * POST请求，Map形式数据
	 *
	 * @param url    请求地址
	 * @param header 请求头
	 * @param param  请求数据
	 */
	private static String sendPost(String url, Map<String, Object> header, Map<String, String> param) {
		return httpPostRequest(url, header, param);
		
	}



	private static SSLContext getSSLContext() throws RuntimeException {
		try {
			javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
			javax.net.ssl.TrustManager tm = new miTM();
			trustAllCerts[0] = tm;
			SSLContext sslContext = SSLContext.getInstance("SSL");
			sslContext.init(null, trustAllCerts, null);
			return sslContext;
		} catch (Exception e) {
			throw new RuntimeException("获取SSLContext失败", e);
		}
	}
	
	private static HostnameVerifier getHostnameVerifier() {
		HostnameVerifier hostnameVerifier = new HostnameVerifier() {
			@Override
			public boolean verify(String urlHostName, SSLSession session) {
				return true;
			}
		};
		return hostnameVerifier;
	}
	
	
	static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
		@Override
		public java.security.cert.X509Certificate[] getAcceptedIssuers() {
			return null;
		}
		
		public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
			return true;
		}
		
		public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
			return true;
		}
		
		@Override
		public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
			return;
		}
		
		@Override
		public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
			return;
		}
	}
	
}
